/*
 * Copyright 2015 CPE Lyon - IRC 2013/2016 - Cours de programmation réseau - Groupe H
 *
 * This file is part of BOTT.
 *
 * BOTT is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
 *
 * BOTT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with BOTT. If not, see http://www.gnu.org/licenses/.
 */

/*
 * Serveur de messagerie.
 *
 * Gère un ensemble de clients et de salons.
 */

#include <pthread.h>
#include "protocole.h"
#include "serveur.h"
#include "fonctions.h"
#include "traitements-serveur.h"
#include "fonctions-serveur.h"

int main() {

    int maxClients = getMaxClientsNumber();
    int maxChats = getMaxChatsNumber();

    printf("\033[H\033[2J");
    printf("%s\e[1m< BOTT server is running >\t\n", KRED);
    printf("%sCurrent settings:\n", KBLU);
    printf("\tMax total client number: [%d]\n", maxClients*maxChats);
    printf("\tMax client number per chat: [%d]\n", maxClients);
    printf("\tMax chat number: [%d]\n", maxChats);
    printf("\tDebug mode activated: [%s]\n", (isDebugActivated()) ? "yes" : "no");
    printf("\tPID: [%d]\n\n", getpid());

    client listClients[maxClients*maxChats];
    chat listChats[maxChats];

    int socketDesc, receivedLen;
    socklen_t addrLen;
    struct sockaddr_in clientAddr, serverAddr;
    pthread_t threadTreatment;

    /* Initialisation */
    init(listClients, listChats);

    /* Création du socket */
    if ((socketDesc = socket(PF_INET, SOCK_DGRAM, 0)) == -1) {
        perror("Socket creation error");
        return EXIT_FAILURE;
    }

    /* Attacher */
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);
    serverAddr.sin_port = htons(SERVER_PORT);
    if (bind(socketDesc, (struct sockaddr *) &serverAddr, sizeof serverAddr) == -1) {
        perror("Socket bind error");
        return EXIT_FAILURE;
    }

    /* Attente infinie de messages */
    while(1) {

        addrLen = sizeof(clientAddr);
        bimp_msg receivedData;

        receivedLen = recvfrom(socketDesc, &receivedData, sizeof receivedData, 0, (struct sockaddr *) &clientAddr, &addrLen);
        if (receivedLen == -1) {
            perror("Data reception error");
            return EXIT_FAILURE;
        } else {
            threadData transmitData;
            transmitData.socketDesc = socketDesc;
            transmitData.receivedData = receivedData;
            transmitData.clientAddr = clientAddr;
            transmitData.listClients = listClients;
            transmitData.listChats = listChats;
            if (pthread_create(&threadTreatment, NULL, messageTreatment, &transmitData) != 0) {
                perror("Thread creation error");
                return EXIT_FAILURE;
            }
        }

    }

}